import { Vec3 } from '@/core/types';
import { BlockType } from '@/blocks/types';
import { WorldManager } from '@/world/WorldManager';
import { RedstoneComponent, RedstonePower, RedstoneConnection, RedstoneState, RedstoneUpdateEvent } from './types';

export class RedstoneSystem {
  private worldManager: WorldManager;
  private state: RedstoneState;
  private updateDelay = 0.1; // 红石更新延迟（秒）
  private maxPowerLevel = 15;
  private updateTimer = 0;

  constructor(worldManager: WorldManager) {
    this.worldManager = worldManager;
    this.state = {
      components: new Map(),
      powerSources: new Map(),
      connections: [],
      updateQueue: []
    };
  }

  public update(deltaTime: number): void {
    this.updateTimer += deltaTime;
    
    if (this.updateTimer >= this.updateDelay && this.state.updateQueue.length > 0) {
      this.processUpdateQueue();
      this.updateTimer = 0;
    }
  }

  public addRedstoneComponent(position: Vec3, blockType: BlockType): void {
    const key = this.getPositionKey(position);
    const component: RedstoneComponent = {
      position: { ...position },
      type: blockType,
      powerLevel: 0,
      isPowered: false,
      lastUpdate: Date.now()
    };

    this.state.components.set(key, component);
    
    // 如果是红石火把，默认提供电力
    if (blockType === BlockType.REDSTONE_TORCH) {
      this.setPowerSource(position, 15);
    }
    
    this.queueUpdate(position);
  }

  public removeRedstoneComponent(position: Vec3): void {
    const key = this.getPositionKey(position);
    this.state.components.delete(key);
    this.state.powerSources.delete(key);
    
    // 移除相关连接
    this.state.connections = this.state.connections.filter(
      conn => !this.positionsEqual(conn.from, position) && !this.positionsEqual(conn.to, position)
    );
    
    this.queueUpdate(position);
    this.updateNeighbors(position);
  }

  public setPowerSource(position: Vec3, powerLevel: number): void {
    const key = this.getPositionKey(position);
    const power: RedstonePower = {
      level: Math.max(0, Math.min(this.maxPowerLevel, powerLevel)),
      source: { ...position },
      lastUpdate: Date.now()
    };

    this.state.powerSources.set(key, power);
    this.queueUpdate(position);
  }

  public removePowerSource(position: Vec3): void {
    const key = this.getPositionKey(position);
    this.state.powerSources.delete(key);
    this.queueUpdate(position);
    this.updateNeighbors(position);
  }

  public getPowerLevel(position: Vec3): number {
    const key = this.getPositionKey(position);
    const component = this.state.components.get(key);
    
    if (component) {
      return component.powerLevel;
    }
    
    const powerSource = this.state.powerSources.get(key);
    return powerSource ? powerSource.level : 0;
  }

  public isPowered(position: Vec3): boolean {
    return this.getPowerLevel(position) > 0;
  }

  private processUpdateQueue(): void {
    const processedPositions = new Set<string>();
    
    while (this.state.updateQueue.length > 0) {
      const position = this.state.updateQueue.shift()!;
      const key = this.getPositionKey(position);
      
      if (processedPositions.has(key)) {
        continue;
      }
      
      processedPositions.add(key);
      this.updateRedstoneAt(position);
    }
  }

  private updateRedstoneAt(position: Vec3): void {
    const blockType = this.worldManager.getBlock(position);
    
    if (!this.isRedstoneComponent(blockType)) {
      return;
    }

    const oldPowerLevel = this.getPowerLevel(position);
    let newPowerLevel = 0;

    // 计算新的电力等级
    if (blockType === BlockType.REDSTONE_TORCH) {
      // 红石火把：如果没有被激活，提供15级电力
      const isActivated = this.isRedstoneBlockPowered(position);
      newPowerLevel = isActivated ? 0 : 15;
    } else if (blockType === BlockType.REDSTONE_WIRE) {
      // 红石线：从相邻方块获取最高电力等级，然后-1
      newPowerLevel = this.calculateWirePowerLevel(position);
    }

    // 更新组件状态
    this.updateComponentPowerLevel(position, newPowerLevel);

    // 如果电力等级改变，更新相邻方块
    if (oldPowerLevel !== newPowerLevel) {
      this.updateNeighbors(position);
      this.onPowerLevelChanged(position, oldPowerLevel, newPowerLevel);
    }
  }

  private calculateWirePowerLevel(position: Vec3): number {
    let maxPower = 0;
    const neighbors = this.getNeighborPositions(position);

    for (const neighbor of neighbors) {
      const neighborPower = this.getPowerLevel(neighbor);
      const neighborBlock = this.worldManager.getBlock(neighbor);
      
      // 从红石火把获得满功率
      if (neighborBlock === BlockType.REDSTONE_TORCH && neighborPower > 0) {
        maxPower = Math.max(maxPower, neighborPower);
      }
      // 从红石线获得功率-1
      else if (neighborBlock === BlockType.REDSTONE_WIRE && neighborPower > 1) {
        maxPower = Math.max(maxPower, neighborPower - 1);
      }
    }

    return maxPower;
  }

  private isRedstoneBlockPowered(position: Vec3): boolean {
    const neighbors = this.getNeighborPositions(position);
    
    for (const neighbor of neighbors) {
      const neighborBlock = this.worldManager.getBlock(neighbor);
      if (neighborBlock === BlockType.REDSTONE_WIRE && this.getPowerLevel(neighbor) > 0) {
        return true;
      }
    }
    
    return false;
  }

  private updateComponentPowerLevel(position: Vec3, powerLevel: number): void {
    const key = this.getPositionKey(position);
    const component = this.state.components.get(key);
    
    if (component) {
      component.powerLevel = powerLevel;
      component.isPowered = powerLevel > 0;
      component.lastUpdate = Date.now();
    }

    // 更新电源
    if (powerLevel > 0) {
      this.setPowerSource(position, powerLevel);
    } else {
      this.removePowerSource(position);
    }
  }

  private updateNeighbors(position: Vec3): void {
    const neighbors = this.getNeighborPositions(position);
    
    for (const neighbor of neighbors) {
      const neighborBlock = this.worldManager.getBlock(neighbor);
      if (this.isRedstoneComponent(neighborBlock)) {
        this.queueUpdate(neighbor);
      }
    }
  }

  private getNeighborPositions(position: Vec3): Vec3[] {
    return [
      { x: position.x + 1, y: position.y, z: position.z },
      { x: position.x - 1, y: position.y, z: position.z },
      { x: position.x, y: position.y + 1, z: position.z },
      { x: position.x, y: position.y - 1, z: position.z },
      { x: position.x, y: position.y, z: position.z + 1 },
      { x: position.x, y: position.y, z: position.z - 1 }
    ];
  }

  private isRedstoneComponent(blockType: BlockType): boolean {
    return blockType === BlockType.REDSTONE_WIRE || 
           blockType === BlockType.REDSTONE_TORCH;
  }

  private queueUpdate(position: Vec3): void {
    // 避免重复添加相同位置
    const exists = this.state.updateQueue.some(pos => this.positionsEqual(pos, position));
    if (!exists) {
      this.state.updateQueue.push({ ...position });
    }
  }

  private onPowerLevelChanged(position: Vec3, oldLevel: number, newLevel: number): void {
    const event: RedstoneUpdateEvent = {
      position: { ...position },
      oldPowerLevel: oldLevel,
      newPowerLevel: newLevel,
      timestamp: Date.now()
    };

    // 这里可以添加事件处理逻辑
    console.log(`Redstone power changed at (${position.x}, ${position.y}, ${position.z}): ${oldLevel} -> ${newLevel}`);
  }

  private getPositionKey(position: Vec3): string {
    return `${Math.floor(position.x)},${Math.floor(position.y)},${Math.floor(position.z)}`;
  }

  private positionsEqual(pos1: Vec3, pos2: Vec3): boolean {
    return Math.floor(pos1.x) === Math.floor(pos2.x) &&
           Math.floor(pos1.y) === Math.floor(pos2.y) &&
           Math.floor(pos1.z) === Math.floor(pos2.z);
  }

  // 调试和状态查询方法
  public getComponentCount(): number {
    return this.state.components.size;
  }

  public getPowerSourceCount(): number {
    return this.state.powerSources.size;
  }

  public getUpdateQueueSize(): number {
    return this.state.updateQueue.length;
  }

  public getDebugInfo(): any {
    return {
      components: this.state.components.size,
      powerSources: this.state.powerSources.size,
      updateQueue: this.state.updateQueue.length,
      connections: this.state.connections.length
    };
  }

  // 清理系统
  public clear(): void {
    this.state.components.clear();
    this.state.powerSources.clear();
    this.state.connections = [];
    this.state.updateQueue = [];
  }
}